#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>


/****************** Constantes *****************/
#define CANTIDAD_PALABRAS_RESERVADAS 15
#define CANTIDAD_MAX_TS	1000
#define ESTADO_INICIAL 0
#define ESTADO_FINAL 36
#define LARGO_MAX_TOKEN 35
#define LARGO_MAX_TOKEN_EXT 45
#define TAM_MAX_TOKENS 5000
#define TAM_MAX_CADENA 30
#define TAM_MAX_VAR 20
#define TRUE 1
#define FALSE 0
#define FLOAT_MAX_VALUE 65536 //16 BITS
#define REAL_MAX_VALUE FLT_MAX

/****************** Tipos de Tokens *****************/
#define CONSTANTE_STRING			1
#define CONSTANTE_INT   			2
#define PUNTO_Y_COMA			  	3
#define DOS_PUNTOS 					4
#define COMA	 				  	5
#define INI_CORCHETE				6
#define FIN_CORCHETE				7
#define INI_PARENTESIS				8
#define FIN_PARENTESIS				9
#define INI_LLAVE					10
#define FIN_LLAVE					11
#define COMILLA						12
#define CADENA						13
#define AND		 					14
#define OR		  					15
#define NEGACION		  			16
#define MAYOR  						17
#define MAYOR_IGUAL					18
#define MENOR  						19
#define MENOR_IGUAL					20
#define IGUAL_IGUAL					21
#define DISTINTO					22
#define SUMA  		 				23
#define RESTA  						24
#define MULTIPLICACION 				25
#define DIVISION  					26
#define IGUAL  						27
#define VARIABLE					28
#define CONSTANTE_FLOAT    	   		29
#define CONSTANTE_BASE_2			30
#define CONSTANTE_BASE_16			31
#define DEFINE 						32
#define ENDDEFINE  					33
//Palabras reservadas 
#define REAL 						34
#define ENTERO 					  	35
#define STRING 					  	36
#define WHILE						37
#define END_WHILE					38
#define IF					 		39
#define END_IF						40
#define PRINT 	 					41
#define RENAME						42
#define ROUND						43
#define TRUNC						44
#define MAIN						45
#define ENDMAIN						46
//Siempre la ultima debe ser ENDMAIN para que imprimar bien el tipo de token.

/****************** Nros de columna para matriz de estados *****************/
#define COLUMNA_LETRA				 0
#define COLUMNA_DIGITO			 	 1
#define COLUMNA_SIMBOLO			 	 2
#define COLUMNA_PUNTO			 	 3
#define COLUMNA_DIVISION		 	 4
#define COLUMNA_NEGACION		 	 5
#define COLUMNA_COMILLAS		 	 6
#define COLUMNA_AND		       		 7
#define COLUMNA_OR		       	 	 8
#define COLUMNA_MENOR			 	 9
#define COLUMNA_MAYOR			 	 10
#define COLUMNA_IGUAL			 	 11
#define COLUMNA_SUMA			     12
#define COLUMNA_RESTA			 	 13
#define COLUMNA_MULTIPLICACION 	 	 14
#define COLUMNA_PUNTO_Y_COMA  	     15
#define COLUMNA_COMA			     16
#define COLUMNA_INI_BLOQUE		 	 17
#define COLUMNA_FIN_BLOQUE		 	 18
#define COLUMNA_INI_CORCHETE		 19
#define COLUMNA_FIN_CORCHETE		 20
#define COLUMNA_INI_PARENTESIS	 	 21
#define COLUMNA_FIN_PARENTESIS	 	 22
#define COLUMNA_DOS_PUNTOS 	 	 	 23
#define COLUMNA_BLANCO		 	 	 24

/****************** Rutinas semanticas *****************/
void iniVar();
void contVar();
void finVar();
void iniCteNum();
void contCteNum();
void finCteNum();
void iniCteString();
void contCteString();
void finCteString();
void error();
void opDivision();
void opNegacion();
void iniAnd();
void finAnd();
void iniOr();
void finOr();
void opMenor();
void opMayor();
void opIgual();
void opSuma();
void opResta();
void opMultiplicacion();
void puntoComa();
void coma();
void iniBloque();
void finBloque();
void iniCorchete();
void finCorchete();
void iniParentesis();
void finParentesis();
void nada();
void opMenorIgual();
void opMayorIgual();
void opDistinto();
void iniComent();
void contComent();
void posFinComent();
void finComent();
void posIniComent2();
void iniComent2();
void contComent2();
void posFinComent2();
void finComent2();
void puntoYComa();
void dosPuntos();
void opIgualIgual();
void finAnd();
void iniOr();
void finOr();
void iniCteOtra();
void contCteOtraValor();
void sepCteOtra();
void contCteOtraBase();
void finCteOtraBase2();
void finCteOtraBase16();

/****************** Funcion generica *****************/
void completarToken(int, int);
void analizarLexico(char *);
int inicializacion(char *);
FILE* abrirArchivo(char*, char);
int perteneceALaLista(char*, char);
void inicializarCadena();
void imprimirTablaSimbolos();
void imprimirTokens();
void convertirToken(int, char*, char*);

/****************** Estructuras *****************/
struct strTablaSimbolos {
	char nombre[LARGO_MAX_TOKEN_EXT];
	char tipo[20];
	char valor[30];
	int longitud;
	char rename[LARGO_MAX_TOKEN_EXT];
};
struct strTokens {
	int tipo;
	char valor[LARGO_MAX_TOKEN];
};
struct strPalabrasReservadas {
	char palabra[LARGO_MAX_TOKEN_EXT];
	int numero;
};

/****************** Variables Globales *****************/
char cadena[TAM_MAX_CADENA];
FILE *fuente;
struct strTablaSimbolos tablaSimbolos[CANTIDAD_MAX_TS];
struct strTokens listaTokens[TAM_MAX_TOKENS];
struct strPalabrasReservadas reservadas[CANTIDAD_PALABRAS_RESERVADAS];
char caracterLeido;
int tipoToken;
int yylval;
int cantCaracteres;
char tokenGenerado[LARGO_MAX_TOKEN];
int cantTokens;
int leido;
int cantComentariosAbiertos;
int posUltimoSimbolo;
int lineaLeida = 1;
char generando[TAM_MAX_CADENA];

/****************** Arrays Globales *****************/
char letras[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
		'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
		'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\0' };
char digitos[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0' };
char simbolos[] = { '@', '#', '%', '$', '?', '~', '^', '\0' };
char blancos[] = { '\n', '\t', '\r', ' ', EOF, '\0' };

/***************** MATRICES *****************/
int nuevoEstado[37][26] = {
		{ 1, 2, 36, 3, 6, 34, 10, 12, 14, 16, 19, 21, 23, 24, 25, 26, 27, 28,
				29, 30, 31, 32, 33, 35, 0 }, //0
		{ 1, 1, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 2, 36, 3, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36 },
		{ 36, 3, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36 },
		{ 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
				5, 5 },
		{ 5, 5, 5, 5, 7, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
				5, 5 }, //5
		{ 36, 36, 36, 36, 36, 5, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36 },
		{ 5, 5, 5, 5, 7, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
				5, 5 },
		{ 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
				8, 8 },
		{ 8, 8, 8, 8, 5, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
				8, 8 },
		{ 10, 10, 10, 10, 10, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
				10, 10, 10, 10, 10, 10, 10, 10 }, //10
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 13, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 15, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, //15
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 17, 18, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 20, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, //20
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 22, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, { 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, //25
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, { 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36 }, { 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, //30
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, { 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36 }, { 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36 }, { 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36 },
		{ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
				36, 36, 36, 36, 36, 36, 36, 36 }, //35
		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
				0, 0 } };

void (*proceso[37][26])()= {
	{	iniVar,iniCteNum,error,iniCteNum,opDivision,opNegacion,iniCteString,iniAnd,iniOr,opMenor,opMayor,opIgual,opSuma,opResta,opMultiplicacion,puntoYComa,coma,iniBloque,finBloque,iniCorchete,finCorchete,iniParentesis,finParentesis,dosPuntos,nada},
	{	contVar,contVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar,finVar}, //2
	{	finCteNum,contCteNum,finCteNum,contCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum}, //3
	{	finCteNum,contCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum,finCteNum}, //4
	{	contComent,contComent,contComent,contComent,finComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent}, //5
	{	contComent,contComent,contComent,contComent,posIniComent2,posFinComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent},
	{	nada,nada,nada,nada,nada,iniComent,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	contComent,contComent,contComent,contComent,posIniComent2,iniComent2,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent,contComent},
	{	contComent2,contComent2,contComent2,contComent2,contComent2,posFinComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2},
	{	contComent2,contComent2,contComent2,contComent2,finComent2,posFinComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2,contComent2}, //10
	{	contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString,contCteString},
	{	finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString,finCteString},
	{	error,error,error,error,error,error,error,finAnd,error,error,error,error,error,error,error,error,error,error,error,error,error,error,error,error,error},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	error,error,error,error,error,error,error,error,finOr,error,error,error,error,error,error,error,error,error,error,error,error,error,error,error,error},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada}, //15
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,opDistinto,opMenorIgual,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,opMayorIgual,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada}, //20
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,opIgualIgual,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada}, //25
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada}, //30
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada},
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada}, //35
	{	nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada,nada}
};


/***************** PROGRAMA *****************/
int main(int argc, char *argv[]) {
	char nombreArchivo[200] = "prueba.txt";


	analizarLexico(nombreArchivo);
	imprimirTokens();
	imprimirTablaSimbolos();
	getch();
	return EXIT_SUCCESS;
}

int getEvent(char caracterLeido) {

	if (perteneceALaLista(letras, caracterLeido)) {
		// printf("COLUMNA_LETRA\n");
		return (COLUMNA_LETRA);
	} else if (perteneceALaLista(digitos, caracterLeido)) {
		//printf("COLUMNA_DIGITO\n");
		return (COLUMNA_DIGITO);
	} else if (perteneceALaLista(simbolos, caracterLeido)) {
		//printf("COLUMNA_SIMBOLO\n");
		return (COLUMNA_SIMBOLO);
	} else if (perteneceALaLista(blancos, caracterLeido)) {
		//printf("COLUMNA_BLANCO\n");
		return (COLUMNA_BLANCO);
	}

	//Resto de los caracteres
	switch (caracterLeido) {
	case '+': { //printf("COLUMNA_SUMA\n");
		return (COLUMNA_SUMA);
	}
	case '-': { //printf("COLUMNA_RESTA\n");
		return (COLUMNA_RESTA);
	}
	case '*': { //printf("COLUMNA_MULTIPLICACION\n");
		return (COLUMNA_MULTIPLICACION);
	}
	case '/': { //printf("COLUMNA_DIVISION\n");
		return (COLUMNA_DIVISION);
	}
	case ';': { //printf("COLUMNA_PUNTO_Y_COMA\n");
		return (COLUMNA_PUNTO_Y_COMA);
	}
	case ',': { //printf("COLUMNA_COMA\n");
		return (COLUMNA_COMA);
	}
	case '.': { //printf("COLUMNA_PUNTO\n");
		return (COLUMNA_PUNTO);
	}
	case '"': { //printf("COLUMNA_COMILLAS\n");
		return (COLUMNA_COMILLAS);
	}
	case '>': { //printf("COLUMNA_MAYOR\n");
		return (COLUMNA_MAYOR);
	}
	case '<': { //printf("COLUMNA_MENOR\n");
		return (COLUMNA_MENOR);
	}
	case '=': { //printf("COLUMNA_IGUAL\n");
		return (COLUMNA_IGUAL);
	}
	case '(': { //printf("COLUMNA_INI_PARENTESIS\n");
		return (COLUMNA_INI_PARENTESIS);
	}
	case ')': { //printf("COLUMNA_FIN_PARENTESIS\n");
		return (COLUMNA_FIN_PARENTESIS);
	}
	case '{': { //printf("COLUMNA_INI_BLOQUE\n");
		return (COLUMNA_INI_BLOQUE);
	}
	case '}': { //printf("COLUMNA_FIN_BLOQUE\n");
		return (COLUMNA_FIN_BLOQUE);
	}
	case '[': { //printf("COLUMNA_INI_CORCHETE\n");
		return (COLUMNA_INI_CORCHETE);
	}
	case ']': { //printf("COLUMNA_FIN_CORCHETE\n");
		return (COLUMNA_FIN_CORCHETE);
	}
	case ':': { //printf("COLUMNA_DOS_PUNTOS\n");
		return (COLUMNA_DOS_PUNTOS);
	}
	case '!': { //printf("COLUMNA_NEGACION\n");
		return (COLUMNA_NEGACION);
	}
	case '&': { //printf("COLUMNA_AND\n");
		return (COLUMNA_AND);
	}
	case '|': { //printf("COLUMNA_OR\n");
		return (COLUMNA_OR);
	}
	}

	//Caracter no admitido por el lenguaje. Cortar Proceso.
	exit(printf("ERROR ANALEX: Caracter '%c' no permitido.", caracterLeido));
}

int yylex() {
	//Inicializo variables por cada nuevo token
	int estado = ESTADO_INICIAL;
	int columna = -1;
	yylval = -1;
	tipoToken = 0;
	leido = FALSE;

	while (!feof(fuente) && estado != ESTADO_FINAL) {
		columna = getEvent(caracterLeido);

		(proceso[estado][columna])();
		estado = nuevoEstado[estado][columna];

		if (leido == FALSE) {
			caracterLeido = (char) getc(fuente);
			// suma las lineas del archivo ingresado
			if (caracterLeido == '\n') {
				lineaLeida++;
			}
		}
	}

	if (feof(fuente)) {
		columna = getEvent(caracterLeido);
		(proceso[estado][columna])();
		estado = nuevoEstado[estado][columna];
		//Verifica si los comentarios se encuentran correctamnete cerrados
		if (cantComentariosAbiertos > 0) {
			error();
		}
	}

	return tipoToken;
}


void analizarLexico(char* nombreArchivo) {

	if (inicializacion(nombreArchivo) == 1) {
		exit(printf("ERROR: No se pudo abrir el archivo fuente.\n"));
	}

	while (!feof(fuente)) {
		if (leido == FALSE) {
			caracterLeido = (char) getc(fuente);
			// suma las lineas del archivo ingresado
			if (caracterLeido == '\n') {
				lineaLeida++;
			}
		}
		// Carga el tipo de Token
		listaTokens[cantTokens].tipo = yylex();
		if (listaTokens[cantTokens].tipo != 0) {
			//Carga el codigo de Token
			strcpy(listaTokens[cantTokens].valor, tokenGenerado);
			//Se incrementa el contador de tokens
			cantTokens++;
		}
	}
	fclose(fuente);
}


FILE* abrirArchivo(char* nombreArchivo, char modo) {
	if (modo == 'L') {
		return (fopen(nombreArchivo, "r"));
	}
	return (fopen(nombreArchivo, "w"));
}


int inicializacion(char * nombreArchivo) {

	if ((fuente = abrirArchivo(nombreArchivo, 'L')) == NULL) {
		return EXIT_FAILURE;
	}

	// Inicializa la lista de palabras reservadas
	strcpy(reservadas[0].palabra, "DEFINE");
	reservadas[0].numero = DEFINE;
	strcpy(reservadas[1].palabra, "ENDDEFINE");
	reservadas[1].numero = ENDDEFINE;
	strcpy(reservadas[2].palabra, "REAL");
	reservadas[2].numero = REAL;
	strcpy(reservadas[3].palabra, "ENTERO");
	reservadas[3].numero = ENTERO;
	strcpy(reservadas[4].palabra, "STRING");
	reservadas[4].numero = STRING;
	strcpy(reservadas[5].palabra, "WHILE");
	reservadas[5].numero = WHILE;
	strcpy(reservadas[6].palabra, "ENDWHILE");
	reservadas[6].numero = END_WHILE;
	strcpy(reservadas[7].palabra, "IF");
	reservadas[7].numero = IF;
	strcpy(reservadas[8].palabra, "ENDIF");
	reservadas[8].numero = END_IF;
	strcpy(reservadas[9].palabra, "PRINT");
	reservadas[9].numero = PRINT;
	strcpy(reservadas[10].palabra, "RENAME");
	reservadas[10].numero = RENAME;
	strcpy(reservadas[11].palabra, "ROUND");
	reservadas[11].numero = ROUND;
	strcpy(reservadas[12].palabra, "TRUNC");
	reservadas[12].numero = TRUNC;
	strcpy(reservadas[13].palabra, "MAIN");
	reservadas[13].numero = MAIN;
	strcpy(reservadas[14].palabra, "ENDMAIN");
	reservadas[14].numero = ENDMAIN;

	cantTokens = 0;
	cantCaracteres = 0;
	cantComentariosAbiertos = 0;
	posUltimoSimbolo = 0;
	inicializarCadena();

	return EXIT_SUCCESS;
}


void inicializarCadena() {
	int i;
	for (i = 0; i < TAM_MAX_CADENA; i++) {
		cadena[i] = '\0';
		generando[i] = '\0';
	}
}


int perteneceALaLista(char* lista, char caracterLeido) {
	int i;
	for (i = 0; lista[i] != '\0'; i++) {
		if (lista[i] == caracterLeido) {
			return 1;
		}
	}
	return 0;
}

int esPalabraReservada(char *c) {
	int i;
	for (i = 0; i < CANTIDAD_PALABRAS_RESERVADAS; i++) {
		// Compara las palabras, IMPLEMENTAR CASE SENSITIVE
		if (strcmp(reservadas[i].palabra, c) == 0) {
			return reservadas[i].numero;
		}
	}
	return FALSE;
}

void imprimirTokens() {
	FILE *fileTokens;
	char tokenFormateado[LARGO_MAX_TOKEN_EXT];
	int i, j = 0;
	//Abrir archivo para guardar la lista de tokens
	if ((fileTokens = abrirArchivo("ListaTokens.txt", 'E')) == NULL) {
		printf("ERROR: No se pudo abrir el archivo de salida de tokens.\n");
	}
	printf("Lista de Tokens\n\n");
	for (i = 0; i < cantTokens; i++) {
		convertirToken(listaTokens[i].tipo, listaTokens[i].valor,
				tokenFormateado);
		if (i == cantTokens - 1) {
			//Ultimo token
			printf("%-10d %s\n", i + 1, tokenFormateado);
			fprintf(fileTokens, "%-10d %s\n", i + 1, tokenFormateado); // Guardar en archivo
		} else {
			printf("%-10d %s\n", i + 1, tokenFormateado); //Pantalla
			fprintf(fileTokens, "%-10d %s\n", i + 1, tokenFormateado); // Guardar en archivo
		}
		if (j == 19) {
			j = 0;
			printf("Presione una tecla para continuar...\n");

		}
		j++;
	}
	fclose(fileTokens);
}

void imprimirTablaSimbolos() {
	FILE *fileSimbolos;
	int i;

	//Abrir archivo para guardar la tabla de simbolos
	if ((fileSimbolos = abrirArchivo("TablaSimbolos.txt", 'E')) == NULL) {
		printf(
				"ERROR: No se pudo abrir el archivo de salida de la tabla de simbolos.\n");
	}
	//Imprime la tabla de simbolos y guarda en archivo de salida
	printf("\n\nTabla de Simbolos\n");
	printf("%s%33s%20s%18s%18s\n", "Nombre", "Tipo", "Valor", "Longitud", "Rename");
	printf(
			"--------------------------------------------------------------------------------------------------------\n");
	fprintf(fileSimbolos, "%s%33s%20s%18s%18s\n", "Nombre", "Tipo", "Valor", "Longitud", "Rename");
	fprintf(
			fileSimbolos,
			"--------------------------------------------------------------------------------------------------------\n");
	for (i = 0; i < posUltimoSimbolo; i++) {
		if (tablaSimbolos[i].longitud > 0) {
			printf("%-35.33s%-19.17s%-15.13s%-15.0d%-35.33s\n", tablaSimbolos[i].nombre,
					tablaSimbolos[i].tipo, "-", tablaSimbolos[i].longitud,
					tablaSimbolos[i].rename);
			fprintf(fileSimbolos, "%-35.33s%-19.17s%-15.13s%-15.0d%-35.33s\n",
					tablaSimbolos[i].nombre, tablaSimbolos[i].tipo, "-",
					tablaSimbolos[i].longitud, tablaSimbolos[i].rename);
		} else {
			printf("%-35.33s%-19.17s%-15.13s%-15s%-35.33s\n", tablaSimbolos[i].nombre,
					tablaSimbolos[i].tipo, tablaSimbolos[i].valor, "-",
					tablaSimbolos[i].rename);
			fprintf(fileSimbolos, "%-35.33s%-19.17s%-15.13s%-15s%-35.33s\n",
					tablaSimbolos[i].nombre, tablaSimbolos[i].tipo,
					tablaSimbolos[i].valor, "-", tablaSimbolos[i].rename);
		}
	}
	fclose(fileSimbolos);
}

int buscarTS(char *simbolo) {
	int i;
	for (i = 0; i < posUltimoSimbolo; i++) {
		if (strcmp(tablaSimbolos[i].nombre, simbolo) == 0) {
			return (i);
		}
	}
	return (-1);
}


int agregarTS(struct strTablaSimbolos simbolo) {

	//Se comprueba que el simbolo no exista
	if ((yylval = buscarTS(simbolo.nombre)) != -1) {
		return yylval; //Ya existe, no se agrega
	}
	//Se agrega a la tabla
	tablaSimbolos[posUltimoSimbolo] = simbolo;
	//Se guarda la posicion donde se agrego
	yylval = posUltimoSimbolo;
	//Se incrementa el contador de simbolos
	posUltimoSimbolo++;
	return (posUltimoSimbolo - 1);
}

void convertirToken(int tipoToken, char *valor, char *salida) {
	int i;
	//Inicializa la salida
	for (i = 0; i < LARGO_MAX_TOKEN_EXT; i++) {
		salida[i] = '\0';
	}
	salida[0] = '<';
	salida[1] = ' ';
	if (tipoToken == VARIABLE) {
		//Variable
		strcat(salida, "ID:");
		strcat(salida, valor);
	} else {
		if (DEFINE <= tipoToken && ENDMAIN >= tipoToken) {
			//Palabra reservada
			strcat(salida, "RSV:");
			strcat(salida, valor);
		} else {
			if (tipoToken == CONSTANTE_BASE_2) {
				//Palabra reservada
				strcat(salida, "CTE_BASE_2:");
				strcat(salida, valor);
			} else {
				if (tipoToken == CONSTANTE_BASE_16) {
					//Palabra reservada
					strcat(salida, "CTE_BASE_16:");
					strcat(salida, valor);
				} else {
					//Otro
					strcat(salida, valor);
				}
			}
		}
	}
	strcat(salida, " >");
}

void iniVar() {
	//  printf(" \n iniVar,");
	cantCaracteres = 1;
	inicializarCadena();
	strcpy(generando, "Variable o Palabra Reservada");
	cadena[cantCaracteres - 1] = caracterLeido;
}

void contVar() {
	//  printf(" contVar,");
	cantCaracteres++;
	cadena[cantCaracteres - 1] = caracterLeido;
}

void finVar() {
	//  printf("finVar \n");
	struct strTablaSimbolos simbolo;

	leido = TRUE; //Indica que no debe leerse otro caracter

	//Se verifica si es una palabra reservada
	if ((tipoToken = esPalabraReservada(cadena)) != 0) {
		strcpy(tokenGenerado, cadena);
		return; //Se vuelve, no hay que agregar a la TS
	}

	tipoToken = VARIABLE;

	// printf("token: %s\n", cadena);
	if (cantCaracteres > TAM_MAX_VAR) {
		exit(
				printf(
						"\nERROR ANALEX: La variable '%s' excede la cantidad maxima de caracteres permitidos(%d).\n",
						cadena, TAM_MAX_VAR));
	}
	strcpy(tokenGenerado, cadena);
	//Agregar a TS
	strcpy(simbolo.nombre, tokenGenerado);
	strcpy(simbolo.tipo, "ID");
	strcpy(simbolo.valor, "");
	simbolo.longitud = 0;
	strcpy(simbolo.rename, "-");
	agregarTS(simbolo);
}

void iniCteNum() {
	// printf("\n iniCteNum,");
	cantCaracteres = 1;
	inicializarCadena();
	strcpy(generando, "Constante Numerica");
	cadena[cantCaracteres - 1] = caracterLeido;
}

void contCteNum() {
	//printf(" iniCteNum,");
	cantCaracteres++;
	if (cantCaracteres == TAM_MAX_CADENA) {
		printf(
				"ERROR ANALEX: El valor '%s' esta fuera del rango numerico permitido(%d). \n",
				cadena, TAM_MAX_VAR);
		//getch();
		exit(1);
	}
	cadena[cantCaracteres - 1] = caracterLeido;
}

void finCteNum() {
	//printf("f inCteNum\n");
	//Manjo todas las constantes numericas como float
	float valor;
	char** pointer = NULL;
	struct strTablaSimbolos simbolo;
	int i;
	leido = TRUE; //Indica que no debe leerse otro caracter

	strcpy(tokenGenerado, cadena);

	//Convierto la cadena a float
	valor = strtod(cadena, pointer);
	if (valor < 0) {
		valor *= -1;
	}

	//Verificar si se esta fuera del rango del float
	if (valor > FLOAT_MAX_VALUE) { // FLT_MAX
		printf("\nANALEX ERROR: El valor '%s' esta fuera del rango numerico permitido (%d). Linea %d.\n",
								cadena, FLOAT_MAX_VALUE, lineaLeida);
		getch();
		exit(1);
	}

	for (i = 0; tokenGenerado[i] != '\0'; i++) {
		if (tokenGenerado[i] == '.') {
			tipoToken = CONSTANTE_FLOAT;
			strcpy(simbolo.tipo, "CONSTANTE_FLOAT");
			break;
		} else {
			tipoToken = CONSTANTE_INT;
			strcpy(simbolo.tipo, "CONSTANTE_INT");
		}
	}

	strcpy(tokenGenerado, cadena);

	//Agregar a TS
	strcpy(simbolo.nombre, tokenGenerado);
	strcpy(simbolo.valor, tokenGenerado);
	simbolo.longitud = 0;
	strcpy(simbolo.rename, "-");
	agregarTS(simbolo);
}

void iniCteString() {
	//printf("\n iniCteString,");
	cantCaracteres = 1;
	inicializarCadena();
	strcpy(generando, "Constante String");
	cadena[cantCaracteres - 1] = caracterLeido;
}

void contCteString() {
	//printf(" contCteString,");
	cantCaracteres++;

	if (cantCaracteres == TAM_MAX_CADENA) {
		printf(
				"ERROR ANALEX: La constante '%s' excede la cantidad maxima de caracteres permitidos para un string (%d).\n",
				cadena, TAM_MAX_CADENA);
		//getch();
		exit(1);
	}
	cadena[cantCaracteres - 1] = caracterLeido;
}

void finCteString() {
	//printf("finCteString\n");
	struct strTablaSimbolos simbolo;
	tipoToken = CONSTANTE_STRING;
	strcpy(tokenGenerado, cadena);

	//Agregar a TS
	strcpy(simbolo.nombre, tokenGenerado);
	strcpy(simbolo.tipo, "CONSTANTE_STRING");
	strcpy(simbolo.valor, tokenGenerado);
	simbolo.longitud = cantCaracteres - 2; // no cuento las dos doble comillas
	strcpy(simbolo.rename, "-");
	agregarTS(simbolo);
	leido = TRUE; //Indica que no debe leerse otro caracter
}

void opSuma() {
	//printf("opSuma\n");
	completarToken(1, SUMA);
}

void opResta() {
	//printf("opResta\n");
	completarToken(1, RESTA);
}

void opMultiplicacion() {
	//printf("opMultiplicacion\n");
	completarToken(1, MULTIPLICACION);
}

void opDivision() {
	//printf("opDivision\n");
	completarToken(1, DIVISION);
}

void iniBloque() {
	//printf("iniBloque\n");
	completarToken(1, INI_LLAVE);
}

void finBloque() {
	//printf("finBloque\n");
	completarToken(1, FIN_LLAVE);
}

void iniCorchete() {
	//printf("iniCorchete\n");
	completarToken(1, INI_CORCHETE);
}

void finCorchete() {
	//printf("finCorchete\n");
	completarToken(1, FIN_CORCHETE);
}

void puntoComa() {
	// printf("puntoComa\n");
	completarToken(1, PUNTO_Y_COMA);
}

void coma() {
	//printf("coma\n");
	completarToken(1, COMA);
}

void dosPuntos() {
	//printf("dosPuntos\n");
	completarToken(1, DOS_PUNTOS);
}

void opNegacion() {
	//printf("opNegacion\n");
	completarToken(1, NEGACION);
}

void opIgual() {
	// printf("opIgual\n");
	completarToken(1, IGUAL);
}

void opMayor() {
	//printf("opMayor\n");
	completarToken(1, MAYOR);
}

void opMenor() {
	//printf("opMenor\n");
	completarToken(1, MENOR);
}

void igualIgual() {
	// printf("igualIgual\n");
	completarToken(2, IGUAL_IGUAL);
}

void opMayorIgual() {
	// printf("opMayorIgual\n");
	completarToken(2, MAYOR_IGUAL);
}

void opMenorIgual() {
	//printf("opMenorIgual\n");
	completarToken(2, MENOR_IGUAL);
}

void opDistinto() {
	//printf("opDistinto\n");
	completarToken(2, DISTINTO);
}

void puntoYComa() {
	//	printf("puntoYComa\n");
	completarToken(1, PUNTO_Y_COMA);
}

void opIgualIgual() {
	//printf("opIgualIgual\n");
	completarToken(2, IGUAL_IGUAL);
}

void iniAnd() {
	//printf("iniAnd\n");
	completarToken(1, AND);
	strcpy(generando, "Operador AND");
}

void finAnd() {
	//printf("finAnd\n");
	completarToken(2, AND);
}

void iniOr() {
	//printf("iniOr\n");
	completarToken(1, OR);
	strcpy(generando, "Operador OR");
}

void finOr() {

	// printf("finOr\n");

	completarToken(2, OR);

}

void completarToken(int cantCarac, int tipo) {
	// printf("completarToken\n");
	tipoToken = tipo;
	if (cantCarac == 1) {
		inicializarCadena();
	}
	cantCaracteres = cantCarac;

	cadena[cantCaracteres - 1] = caracterLeido;
	strcpy(tokenGenerado, cadena);
}

void nada() {
	//printf("nada, ");
	if (leido == TRUE) {
		leido = FALSE;
	} else {
		leido = TRUE;
	}
}

void error() {
	//	printf("error\n");
	if (strcmp(generando, "") != 0) {
		exit(
				printf("ERROR ANALEX: Generando %s, Linea %d\n.", generando,
						lineaLeida));
	} else {
		exit(printf("ERROR ANALEX: Linea: %d , Caracter: %c\n", lineaLeida, caracterLeido));
	}
}

void iniComent() {
	//printf("iniComent\n");
	tipoToken = 0; //Limpio el tipoToken seteado por opDiv
	strcpy(generando, "Comentario Simple");
	cantComentariosAbiertos++; //Se abre un bloque

	if (cantComentariosAbiertos > 1) {
		exit(printf("ERROR ANALEX: Error al crear comentario.\n"));
	}
}

void contComent() {
	//printf("contComent\n");
	//Nada
}

void posFinComent() {
	// printf("posFinComent\n");
	//Nada
}

void finComent() {
	//printf("finComent\n");
	cantComentariosAbiertos--; //Se cierra un bloque

	if (cantComentariosAbiertos > 0) {
		exit(printf("ERROR ANALEX: Error al crear comentario.\n"));
	}
}

void posIniComent2() {
	//printf("posIniComent2\n");
	//Nada
}

void iniComent2() {
	// printf("iniComent2\n");
	cantComentariosAbiertos++; //Se abre un bloque
	strcpy(generando, "Comentario Anidado");
	if (cantComentariosAbiertos > 2) {
		exit(
				printf(
						"ERROR ANALEX: Error al crear comentario de segundo nivel.\n"));
	}
}

void contComent2() {
	//printf("contComent2\n");
	//Nada
}

void posFinComent2() {
	//printf("posFinComent2\n");
	//Nada
}

void finComent2() {
	//printf("finComent2\n");
	cantComentariosAbiertos--; //Se cierra un bloque

	if (cantComentariosAbiertos > 1) {
		exit(
				printf(
						"ERROR ANALEX: Error al crear comentario de segundo nivel.\n"));
	}
}
/*
 void iniParentesis() {
 // printf("iniParentesis\n");
 completarToken(1, INI_PARENTESIS);
 }
 */

void iniParentesis() {

	//Guardo el parentesis que ya tengo parseado.
	char caracterLeidoAnterior = caracterLeido;
	int i = 0;
	char cadenaTemp[TAM_MAX_CADENA];
	//En este punto empieza el reconocimiento de una posible constante en otra base.
	//Leo el siguiente caracter.
	caracterLeido = (char) getc(fuente);

	//Si leo un espacio en blanco entonces solamente debo parsear el parentesis.	
	if (caracterLeido == ' ') { //Vuelvo el cursos un caracter hacia atras.
		ungetc(caracterLeido, fuente);
		caracterLeido = caracterLeidoAnterior;
		completarToken(1, INI_PARENTESIS);

	} else { //En  este momento tenemos parseado un "INIPARENTESIS" y el siguiente caracter no es un espacio, por lo que consideramos
			 //que sea un posible inicio de constante en otra base.

		//Almaceno en una cadena temporal los caracteres que voy parseando.
		cantCaracteres = 2;
		cadenaTemp[0] = '('; // Agrego el parentesis como primer caracter.
		cadenaTemp[cantCaracteres - 1] = caracterLeido; //Agrego luego el caracter leido.

		//Empiezo a evaluar que tipo de token estoy parseando.
		//Leo el siguiente caracter.
		caracterLeido = (char) getc(fuente);
		while ((perteneceALaLista(letras, caracterLeido))
				|| (perteneceALaLista(digitos, caracterLeido))) {
			cantCaracteres++;
			cadenaTemp[cantCaracteres - 1] = caracterLeido;
			caracterLeido = (char) getc(fuente);
		}

		cadenaTemp[cantCaracteres] = caracterLeido;

		//Si despues de la variable leo una coma, estoy en una constante en otra base, es el unico token valido.
		if (caracterLeido == ',') {

			inicializarCadena();
			strcpy(generando, "Constante en otra base.");
			for (i = 0; i <= cantCaracteres; i++)
				cadena[i] = cadenaTemp[i];

			caracterLeido = (char) getc(fuente);
			cantCaracteres++;
			contCteOtraBase();

		} else {
			//Si no es coma, no tengo una constante en otra base, por lo que hago el unget y tengo que reconocer solo el iniparentesis.
			for (i = cantCaracteres; i > 0; i--)
				ungetc(cadenaTemp[i], fuente);
			//Reconozco un INI_PARENTESIS, cargo el valor de caracter leido y vuelvo al estado inicial.	
			caracterLeido = cadenaTemp[0];
			completarToken(1, INI_PARENTESIS);

		}

	}
}

//Esta funcion no la invoco mediante el automata, la invoco desde iniParentesis cuando reconozco constante en otra base.
void iniCteOtra() {
	//Llegado este punto, ya se que lo que estoy por parsear es una constante en otra base.
	//Tengo que inicializar la cadena y agregar el INI_PARENTESIS como primer caracter.
	printf("valor leido %c", caracterLeido);

	//Inicializo la cadena y copio el INI_PARENTESIS al inicio de la misma.
	inicializarCadena();
	strcpy(generando, "Constante en otra base.");
	cantCaracteres = 1;
	cadena[cantCaracteres - 1] = '(';

}

void contCteOtraValor() {

	printf("contCteOtraValor\n");

	//printf("\nleido %c",caracterLeido);
	cantCaracteres++;
	cadena[cantCaracteres - 1] = caracterLeido;
}

void sepCteOtra() {
	printf("sepCteOtra\n");
	printf("\nleido %c", caracterLeido);
	cantCaracteres++;
	cadena[cantCaracteres - 1] = caracterLeido;
}

void contCteOtraBase() {
	printf("contConstOtraValor\n");

	//printf("\nleido %d",caracterLeido);

	//En este metodo esta la logica que diferencia una constante en binario o hexa.
	if (caracterLeido == '2') {
		printf("Binario\n");
		cantCaracteres++;
		cadena[cantCaracteres - 1] = caracterLeido;

		caracterLeido = (char) getc(fuente);
		finCteOtraBase2();
	} else {
		if (caracterLeido == '1') { //Almaceno el uno en la cadena.
			cantCaracteres++;
			cadena[cantCaracteres - 1] = caracterLeido;
			//Leo el otro caracter que tiene que ser un 6, sino error.
			caracterLeido = (char) getc(fuente);
			if (caracterLeido == '6') {
				cantCaracteres++;
				cadena[cantCaracteres - 1] = caracterLeido;

				caracterLeido = (char) getc(fuente);
				finCteOtraBase16();
			} else {
				error();
			}
		} else {
			error();
		}
	}
}

void finCteOtraBase2() {
	struct strTablaSimbolos simbolo;
	//printf("finConstOtra\n");
	//printf("\nleido %c",caracterLeido);
	cantCaracteres++;
	cadena[cantCaracteres - 1] = caracterLeido;
	tipoToken = CONSTANTE_BASE_2;
	completarToken(cantCaracteres, CONSTANTE_BASE_2);
	strcpy(tokenGenerado, cadena);

	//Agregar a TS
	strcpy(simbolo.nombre, tokenGenerado);
	strcpy(simbolo.tipo, "CONSTANTE_BASE_2");
	strcpy(simbolo.valor, tokenGenerado);
	simbolo.longitud = 0;
	strcpy(simbolo.rename, "-");
	agregarTS(simbolo);
	leido = FALSE; //Indica que no debe leerse otro caracter
}

void finCteOtraBase16() {
	struct strTablaSimbolos simbolo;
	//printf("finConstOtra\n");
	//printf("\nleido %c",caracterLeido);
	cantCaracteres++;
	cadena[cantCaracteres - 1] = caracterLeido;
	tipoToken = CONSTANTE_BASE_16;
	completarToken(cantCaracteres, CONSTANTE_BASE_16);
	strcpy(tokenGenerado, cadena);

	//Agregar a TS
	strcpy(simbolo.nombre, tokenGenerado);
	strcpy(simbolo.tipo, "CONSTANTE_BASE_16");
	strcpy(simbolo.valor, tokenGenerado);
	simbolo.longitud = 0;
	strcpy(simbolo.rename, "-");
	agregarTS(simbolo);
	leido = FALSE; //Indica que no debe leerse otro caracter
}

void finParentesis() {
	// printf("finParentesis\n");
	completarToken(1, FIN_PARENTESIS);
}

